package com.ebook.server.service;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;

import com.ebook.core.domain.User;
import com.ebook.core.util.UserUtil;
import com.ebook.util.DataUtil;
import com.ebook.util.DateUtil;
import com.ebook.util.ErrorCode;
import com.ebook.util.MD5;
import com.ebook.util.SendAttachment;
import com.ebook.util.Status;

/**
 * 用户管理的Service层
 * @author   潘吉友
 * @Date	 2013-2-25
 */
@Service
@Transactional
public class UserService {

	@Resource
	private JdbcTemplate jdbcTemplate;
	
	@Resource
	private UserDeviceService userDeviceService;
	
	@Resource
	private DeviceBookService deviceBookService;
	
	@Resource
	private ReturnNoteService returnNoteService; 
	
	private static Log logger = LogFactory.getLog(UserService.class);
	
	public boolean isCertified(int uid,String checkcode){
	    if(checkcode == null){
	    	logger.info("fasle");
	    	return false;
	    }
	    Map<String,Object> umap = queryById(uid);
	    if(umap != null && checkcode.equals(umap.get("checkcode").toString().trim())){
	    	logger.info("true");
	    	return true;
	    }
	   logger.info("fasle");
		return false;
	}
	

	/**
	 * 重置密码功能
	 * @param email
	 * @param password
	 * @param password1
	 * @return 重置成功转重置成功页面；失败转到重置密码页面
	*/
	public ModelAndView resetPsw(String email, String password, String password1) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.SUCCESS;
		if (!DataUtil.checkString(password, password1)) {
			status = Status.REJECTED + ":" + ErrorCode.MODIFY_PASSWORD_FAIL;
			modelView.setViewName("/user/resetpass");
		} else {
			String passwordMd5 = MD5.getEncryptedPwd(password);
			if (!modifyPswByEmail(passwordMd5, email)) {
				status = Status.REJECTED + ":" + ErrorCode.MODIFY_PASSWORD_FAIL;
				modelView.setViewName("/user/resetpass");
			}else{
				modelView.setViewName("/user/resetpsw_s");
			}
		}
		modelMap.put("status", status);
		modelMap.put("email", email);
		modelView.addAllObjects(modelMap);
		return modelView;
	}
	
	
	/**
	 * 核对email和动态码，成功跳转到重置密码页面，失败跳转到错误页面
	 * @param email
	 * @param checkcode
	 * @return 视图
	*/
	public ModelAndView editPsw(String email, String checkcode) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		if(checkCode(email,checkcode)){
			modelMap.put("email", email);
			modelMap.put("checkcode", checkcode);
			modelView.setViewName("/user/resetpass");
		}else{
			modelMap.put("status", "您的邮箱或动态码错误！");
			modelView.setViewName("/user/linkerror");
		}
		modelView.addAllObjects(modelMap);
		return modelView;
	}
	
	/**
	 * 给email地址发邮件
	 * @param email
	 * @param request
	 * @return 成功失败信息
	*/
	@SuppressWarnings("unused")
	public ModelAndView sendPswByEmail(String email) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		String status = Status.SUCCESS;
		if(email !=null || email != ""){
				String checkcode = DataUtil.randomCheckCode();
				if(!SendAttachment.sendPswByMail(email,checkcode)){
					status = Status.REJECTED + ":" + ErrorCode.EMAIL_SEND_FAIL;
				}
				updataCheckCode(email,checkcode);
       }else{
    	   status = Status.REJECTED + ":" + ErrorCode.EMAIL_SEND_FAIL;
       }
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}
	
	/**
	 * 返回没有用户权限的试图
	 * @param modelView
	 * @param modelMap
	 * @return ModelAndView
	 */
	public ModelAndView notLoginView(ModelAndView modelView, Map<String, Object> modelMap) {
		modelMap.put("error", true);
		modelMap.put("errormsg", "用户不存在或您没有权限查看！");
		String status = Status.REJECTED + ":" + ErrorCode.NOT_LOGIN;
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}
	
	/**
	 * 注册模块
	 * @param email
	 * @param password
	 * @param name
	 * @param type
	 * @return ModelAndView
	*/
	public ModelAndView regist(String email,String password,String name,String type) {
		ModelAndView modelView = new ModelAndView();
    	Map<String,Object> modelMap=new HashMap<String,Object>();  
    	String status = Status.SUCCESS;
		if (name == null || name.trim().isEmpty() ) {
			status = Status.REJECTED + ":" + ErrorCode.INVALID_USER_NAME;
		}
		else if (email == null || email.trim().isEmpty()) {
			status = Status.REJECTED + ":" + ErrorCode.INVALID_EMAIL;
		}
		else if (password == null || password.trim().isEmpty()) {
			status = Status.REJECTED + ":" + ErrorCode.INVALID_PASSWORD;
		}
		else {
			if (isUserEmailExist(email)) {
				status = Status.REJECTED + ":" + ErrorCode.DUPLICATE_EMAIL;
 			}
			else {
				User user = registerUser(name, email, password, type);
				if (user == null) {
					status = Status.REJECTED + ":" + ErrorCode.UNKNOWN;
				}else{
					 modelMap.put("user", user);
				}
			}
		}
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
        return modelView;
	}
	
	public ModelAndView login(String email, String password,String device_id,
			HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String,Object> modelMap=new HashMap<String,Object>();
		String status = Status.SUCCESS;
		if(email == null){
			status = Status.REJECTED + ":" + ErrorCode.INVALID_EMAIL;
		}
		if (!isUserEmailExist(email)) {
			status = Status.REJECTED + ":" + ErrorCode.INVALID_EMAIL;
		}
		else {
			User user = queryByEmailAndPass(email, password);
			if (user == null) {
				status = Status.REJECTED + ":" + ErrorCode.INVALID_PASSWORD;
			}else{
				if("".equals(device_id) || device_id == null){
					status = Status.REJECTED + ":" + ErrorCode.DEVICE_ID_FAIL;
				}else{
					if(userDeviceService.isExist(user.getId(), device_id)){
//						HttpSession session=request.getSession();  
//			            //处理用户登录(保持同一时间同一账号只能在一处登录)   
//			             userLoginHandle(request,user);  
//			             //添加用户与HttpSession的绑定   
//			             SessionCounterListener.USER_SESSION.put(user.getEmail(), session);  
//			             //添加sessionId和用户的绑定   
//			             SessionCounterListener.SESSIONID_USER.put(session.getId(), user);  
//			               
//			             session.setAttribute("email", user.getEmail());  
//			             session.removeAttribute("userMsg"); 
//						request.getSession().setAttribute("loginuser", user);
						modelMap.put("user", user);
					}else{
						if(userDeviceService.queryCount(user.getId())>= 10){
							status = Status.REJECTED + ":" + ErrorCode.DEVICE_ID_EXCEED_5;
						}else{
							userDeviceService.add(user.getId(),device_id);
//							HttpSession session=request.getSession();  
//				            //处理用户登录(保持同一时间同一账号只能在一处登录)   
//				             userLoginHandle(request,user);  
//				             //添加用户与HttpSession的绑定   
//				             SessionCounterListener.USER_SESSION.put(user.getEmail(), session);  
//				             //添加sessionId和用户的绑定   
//				             SessionCounterListener.SESSIONID_USER.put(session.getId(), user);  
//				               
//				             session.setAttribute("user", user);  
//				             session.removeAttribute("userMsg");  
//							request.getSession().setAttribute("loginuser", user);
							modelMap.put("user", user);
						}
					}
				}
			}
		}
        modelMap.put("status", status);
//        modelView.setViewName("/user/userinfo");
        modelView.addAllObjects(modelMap);
        return  modelView;
	}
	
//	public static void userLoginHandle(HttpServletRequest request,User user){  
//	    //当前sessionId   
//	    String sessionId = request.getSession().getId();  
//	    System.out.println("sessionId："+sessionId);
//	    //删除当前sessionId绑定的用户，用户--HttpSession  
//	    SessionCounterListener.USER_SESSION.remove(SessionCounterListener.SESSIONID_USER.remove(sessionId));  
//	      
//	    //删除当前登录用户绑定的HttpSession   
//	    HttpSession session = SessionCounterListener.USER_SESSION.remove(user.getEmail());  
//	    if(session!=null){  
//	    	SessionCounterListener.SESSIONID_USER.remove(session.getId());  
//	        session.removeAttribute("user");  
//	        session.setAttribute("userMsg", "您的账号已经在另一处登录了,你被迫下线!");  
//	    }  
//	}  

	public ModelAndView modifyPassword(String email,String oldPassword,String newPassword,HttpServletRequest request) {
		ModelAndView modelView = new ModelAndView();
		Map<String, Object> modelMap = new HashMap<String, Object>();
		// long userId =Long.valueOf(request.getParameter("userId")) ;
		String status = Status.SUCCESS;
		if(!isUserEmailExist(email)){
			status = Status.REJECTED + ":" + ErrorCode.INVALID_EMAIL;
		}
		if (!modifyPassword(email, oldPassword, newPassword)) {
			status = Status.REJECTED + ":" + ErrorCode.INVALID_PASSWORD;
		}
		modelMap.put("status", status);
		modelView.addAllObjects(modelMap);
		return modelView;
	}

	/**
	 * 通过email和密码获取用户信息
	 * @param email 
	 * @param password
	 * @return 用户对象
	*/
	public User queryByEmailAndPass(String email, String password) {
		try {
			String sql = "select * from user where email=? and password=?";
			logger.info(sql);
			Map<String, Object> map = jdbcTemplate.queryForMap(sql, email, password);
			User user = UserUtil.parseUser(map);
			return user;
		} catch (DataAccessException e) {
			logger.error("获取用户信息操作数据库错误" + e.getMessage()); 
			return null;
		}
	}
	
	public Map<String,Object> queryById(int uid) {
		try {
			String sql = "select * from user where id=?";
			logger.info(sql);
			Map<String, Object> map = jdbcTemplate.queryForMap(sql, uid);
			return map;
		} catch (DataAccessException e) {
			return null;
		}
	}
	
	public List<Map<String,Object>> list() {
		try {
			String sql = "select * from user";
			logger.info(sql);
			List<Map<String,Object>> maps = jdbcTemplate.queryForList(sql);
			return maps;
		} catch (DataAccessException e) {
			return null;
		}
	}


	/**
	 * 完成用户的注册
	 * @param name      用户名
	 * @param email     email
	 * @param password  密码
	 * @param type      用户类型
	 * @return 完成注册的用户对象
	*/
	public User registerUser(String name, String email, String password, String type) {
		String sql1 = "insert into user (id, name, email, password, type,checkcode) values (0, ?, ?, ?, ?, ?)";
		String sql2 = "select id, reg_time from user where email=?";
		logger.info(sql1);
		logger.info(sql2);		
		try {
			jdbcTemplate.update(sql1, name, email, password, type,DataUtil.randomCheckCode());
			Map<String, Object> map = jdbcTemplate.queryForMap(sql2, email);
			int id = (Integer)map.get("id");
			Timestamp ts = (Timestamp)map.get("reg_time");
			String regTime = DateUtil.SDF2.format(ts);

			User user = new User(id, email, name, password, type, regTime);
			return user;
		} catch (DataAccessException e) {
			logger.error("插入新用户操作数据库错误" + e.getMessage());
			return null;
		}
	}

	/**
	 * 通过email判断用户是否唯一
	 * @param email
	 * @return true：用户不唯一，false：用户唯一
	 */
	public boolean isUserEmailExist(String email) {
		String sql = "select count(*) FROM user WHERE email=? ";
		logger.info(sql);
		try {
			int cnt = jdbcTemplate.queryForInt(sql, email.trim());
			return cnt > 0;
		} catch (DataAccessException e) {
			logger.error("通过email查询user表失败" + e.getMessage());
			return false;
		}
		
	}

	
	/**
	 * 判断用户Id是否存在
	 * @param uid 用户Id
	 * @return true：用户Id存在，false：不存在
	*/
	public boolean isUserIdExist(int uid) {
		String sql = "select id from user where id=?";
		logger.info(sql);
		try {
			List<Map<String, Object>> ret = jdbcTemplate.queryForList(sql, uid);
			return (ret != null && !ret.isEmpty());
		}
		catch (DataAccessException e) {
			logger.error("通过id查询user表失败" + e.getMessage());
		}
		return false;
	}
	
	/**
	 * 根据用户Id保存修改后的密码
	 * @param email       用户email
	 * @param oldPassword  旧密码
	 * @param newPassword  新密码
	 * @return true：保存完成，false：保存失败
	*/
	public boolean modifyPassword(String email , String oldPassword, String newPassword) {
		String sql1 = "select count(*) from user where email = ? and password = ? ";
		logger.info(sql1);
		try {
			if(jdbcTemplate.queryForInt(sql1,email,oldPassword)==0){
			return false;	
			}
			String sql2 = "update user set password = ? where email = ? and password = ? ";
			logger.info(sql2);
			jdbcTemplate.update(sql2, newPassword,email,oldPassword);	
			return true;
		}
		catch (DataAccessException e) {
			logger.error("更新User表错误" + e.getMessage());
			return false;
		}
	}

	/**
	 * 更新email账号的动态核对码
	 * @param email
	 * @param checkcode 
	*/
	public void updataCheckCode(String email, String checkcode) {
		String updataSql = "update user set checkcode=? where email=? ";
		logger.info(updataSql);
		jdbcTemplate.update(updataSql,checkcode,email);
		
		
	}

	/**
	 * 检查动态码是否有效
	 * @param email
	 * @param checkcode 
	 * @return true：有效；false：无效
	*/
	public boolean checkCode(String email, String checkcode){
		String sql = "select count(*) from user where email=? and checkcode=?";
		logger.info(sql);
		if(jdbcTemplate.queryForInt(sql,email,checkcode)>0){
			return true;
		}
		return false;
		
	}

	/**
	 * 通过email账号修改密码和动态码
	 * @param password
	 * @param email
	 * @return true：成功；false：失败
	*/
	public boolean modifyPswByEmail(String password, String email) {
		String sql1 = "select count(*) from user where email = ?";
		String sql2 = "update user set password=? , checkcode=? where email = ?";
		logger.info(sql1);
		logger.info(sql2);
		if(jdbcTemplate.queryForInt(sql1,email.trim())>0){
			jdbcTemplate.update(sql2,password.trim(),DataUtil.randomCheckCode(),email.trim());
			return true;
		}else{
			return false;
		}
	}
	
	public void loginOut(int uid, String deviceId) {
		userDeviceService.delete(deviceId);
		userDeviceService.delFilePath(uid,deviceId);
		deviceBookService.delete(deviceId);
		returnNoteService.delByDeviceId(deviceId);
	}


	public void setCode() {
		String sql = "select * from user ";
		String sql2 = "update user set verificationCode=? where id=?";
		List<Map<String,Object>> list = jdbcTemplate.queryForList(sql);
		for(Map<String,Object> m : list){
			String str = m.get("email").toString()+":"+m.get("password").toString();
			String verificationCode = MD5.getEncryptedPwd(str);
//			System.out.println(str);
//			System.out.println(str);
			jdbcTemplate.update(sql2, verificationCode,(Integer)(m.get("id")));
		}
		
	}
}
